package ch.ethz.fcl.metrobuzz.algorithm.voronoi.Okabe;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.vecmath.Vector2d;

import ch.ethz.fcl.metrobuzz.spatialindex.object2d.Point2D;
import ch.ethz.fcl.metrobuzz.tools.MBTools;

public class OkabeVoronoiCell {
	private Point2D center;
	private float weight;
	private List<Point2D> edgeVertices;
	private List<Point2D> tempVertices;

	private float centerToOrigin;

	public OkabeVoronoiCell(float x, float y, float weight) {
		this(new Point2D(x, y), weight);
	}

	public OkabeVoronoiCell(Point2D c, float weight) {
		this.center = c;
		this.weight = weight;
		edgeVertices = new ArrayList<Point2D>();
		tempVertices = new ArrayList<Point2D>();
	}

	public float distanceTo(OkabeVoronoiCell another) {
		return center.distance(another.getCenter());
	}

	public void normalizeVertices(float oMinX, float oMinY, float oMaxX,
			float oMaxY, float width, float height) {
		for (int i = 0; i < tempVertices.size(); i++) {
			Point2D p = tempVertices.get(i);
			float normalizeX = oMinX + p.getX() / width * (oMaxX - oMinX);
			float normalizeY = oMinY + p.getY() / height * (oMaxY - oMinY);

			edgeVertices.add(new Point2D(normalizeX, normalizeY));
		}

		Collections.sort(edgeVertices, new Comparator<Point2D>() {
			@Override
			public int compare(Point2D p1, Point2D p2) {
				Vector2d y_axis = new Vector2d(0, 1);
				float angle1 = (float) MBTools.angle(y_axis,
						new Vector2d(p1.getX() - center.getX(), p1.getY()
								- center.getY()));
				float angle2 = (float) MBTools.angle(y_axis,
						new Vector2d(p2.getX() - center.getX(), p2.getY()
								- center.getY()));
				if (angle1 == angle2)
					return 0;
				else if (angle1 > angle2)
					return 1;
				else
					return -1;
			}
		});
	}

	public void resetEdgeVertices() {
		tempVertices = new ArrayList<Point2D>();
		edgeVertices = new ArrayList<Point2D>();
	}

	public void addVertice(Point2D vertex) {
		tempVertices.add(vertex);
	}

	public void setCenterToOrigin(float value) {
		this.centerToOrigin = value;
	}

	public float getCenterToOrigin() {
		return this.centerToOrigin;
	}

	public Point2D getCenter() {
		return center;
	}

	public float getWeight() {
		return weight;
	}

	public List<Point2D> getEdgeVertices() {
		return this.edgeVertices;
	}

	public float getX() {
		return center.getX();
	}

	public float getY() {
		return center.getY();
	}

	@Override
	public String toString() {
		return center.toString() + " " + weight;
	}
}
